/**
 * 生成css代码提示文件
 */
import {
    JUSTIFY_CONTENT_ENUM,
    ALIGN_ITEMS_ENUM,
    CURSOR_ENUM,
    VERTICAL_ALIGN_ENUM,
    GAP_ENUM,
    DISPLAY_ENUM,
    COLORS_NAME_PRESET,
	SNIPPETS_FILE_NAME,
	FLEX_DIRECTION_NAME_ENUM,
	FLEX_DIRECTION_ENUM,
	UNIT_ENUM,
	TEXT_ALIGN_NAME_ENUM,
	TEXT_ALIGN_ENUM
} from '../constant';

import {
    prefixStr
} from './utils';

import {
    changeConsoleColor
} from './colorUtils';

const fs = require('fs');
const path = require('path');
const NUM_ENUM = [1, 2];
// const UNIT_ENUM = ['', 'p', 'rem', 'rpx', 'vh'];
const NUM_WIDTH_UNIT = [1, 2, '1p', '1rem', '1rpx', '1vh'];

const getRegList = () => {

    const cssPrefix = prefixStr(true);

    return [
        {
            className: 'widthOrHeight',
            render() {
                let widthOrHeight = '';
                ['w', 'h'].forEach(d => {
                    NUM_ENUM.forEach(n => {
                        UNIT_ENUM.forEach(u => {
                            widthOrHeight += `.${cssPrefix}${d}-${n}${u}{}`
                        })
                    })
                })
                return widthOrHeight
            }
        },
        {
            className: 'square',
            render() {
                let square = ''
                NUM_ENUM.forEach(n => {
                    UNIT_ENUM.forEach(u => {
                        square += `.${cssPrefix}square-${n}${u}{}`
                    })
                })
                return square
            }
        },
        {
            className: 'minMaxWidthOrHeight',
            render() {
                let minMaxWidthOrHeight = '';
                ['min', 'max'].forEach(mm => {
                    ['w', 'h'].forEach(wh => {
                        NUM_ENUM.forEach(n => {
                            UNIT_ENUM.forEach(u => {
                                minMaxWidthOrHeight += `.${cssPrefix}${mm}-${wh}-${n}${u}{}`
                            })
                        })
                    })
                })
                return minMaxWidthOrHeight
            }
        },
        {
            className: 'objectFit',
            render() {
                let objectFit = '';
                ['fill', 'contain', 'cover', 'none', 'scale-down', 'inherit', 'initial', 'revert', 'unset'].forEach(val => {
                    objectFit += `.${cssPrefix}object-fit-${val}{}`
                })
                return objectFit
            }
        },
        {
            className: 'marginOrPadding',
            render() {
                let marginOrPadding = '';
                ['m', 'p'].forEach(mp => {
                    ['t-', 'r-', 'b-', 'l-', 'x-', 'y-', ''].forEach(trblxy => {
                        ['m-', ''].forEach(m => {
                            NUM_ENUM.forEach(n => {
                                UNIT_ENUM.forEach(u => {
                                    marginOrPadding += `.${cssPrefix}${mp}-${trblxy}${m}${n}${u}{}`
                                })
                            })
                        })
                    })
                })
                return marginOrPadding
            }
        },
        {
            className: 'marginOrPaddingUseAuto',
            render() {
                let marginOrPadding = '';
                ['m', 'p'].forEach(mp => {
                    ['t-', 'r-', 'b-', 'l-', 'x-', 'y-', ''].forEach(trblxy => {
                        marginOrPadding += `.${cssPrefix}${mp}-${trblxy}auto{}`
                    })
                })
                return marginOrPadding
            }
        },
        {
            className: 'zIndex',
            render() {
                let zIndex = '';
                ['m-', ''].forEach(m => {
                    NUM_ENUM.forEach(n => {
                        zIndex += `.${cssPrefix}z-index-${m}${n}{}`
                    })
                })
                return zIndex
            }
        },
        {
            // flex-1 flex-9999
            className: 'flexNum',
            render() {
                let flexNum = '';
                ['null', 'auto', 'none', '0', '1'].forEach(x => {
                    flexNum += `.${cssPrefix}flex-${x}{}`
                })
                return flexNum
            }
        },
        {
            className: 'text-align',
            render() {
                let textAlign = '';
                TEXT_ALIGN_NAME_ENUM.forEach(t => {
                    TEXT_ALIGN_ENUM.forEach(v => {
                        textAlign += `.${cssPrefix}${t}-${v}{}`
                    })
                })
                return textAlign
            }
        },
        {
            className: 'line-height',
            render() {
                let str = '';
                ['lh', 'line-height'].forEach(lh => {
                    [...NUM_WIDTH_UNIT, 'normal', 'unset', 'inherit', 'initial'].forEach(v => {
                        str += `.${cssPrefix}${lh}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            // flex-just-ali
            className: 'flex',
            render() {
                let str = ''
                JUSTIFY_CONTENT_ENUM.forEach(jc => {
                    ALIGN_ITEMS_ENUM.forEach(ai => {
                        str += `.${cssPrefix}flex-${jc}-${ai}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'justify-content',
            render() {
                let str = ''
                JUSTIFY_CONTENT_ENUM.forEach(jc => {
                    str += `.${cssPrefix}justify-content-${jc}{}`
                })
                return str
            }
        },
        {
            className: 'align-items',
            render() {
                let str = ''
                ALIGN_ITEMS_ENUM.forEach(ai => {
                    str += `.${cssPrefix}justify-content-${ai}{}`
                })
                return str
            }
        },
        {
            className: 'flex-direction',
            render() {
                let str = '';
                FLEX_DIRECTION_NAME_ENUM.forEach(t => {
                    FLEX_DIRECTION_ENUM.forEach(v => {
                        str += `.${cssPrefix}${t}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'flex-wrap-value',
            render() {
                let str = '';
                ['inherit', 'initial', 'nowrap', 'wrap', 'wrap-reverse'].forEach(v => {
                    str += `.${cssPrefix}flex-wrap-${v}{}`
                })
                return str
            }
        },
        {
            // 定位方式枚举
            className: 'position',
            render() {
                let str = '';
                ['static', 'relative', 'sticky', 'unset', 'absolute', 'fixed', 'inherit', 'initial'].forEach(v => {
                    str += `.${cssPrefix}position-${v}{}`
                })
                return str
            }
        },
        {
            // 透明度
            className: 'opacity',
            render() {
                let str = ''
                const list = [20, 80, 100]
                list.forEach(n => {
                    str += `.${cssPrefix}opacity-${n}{}`
                })
                return str
            }
        },
        {
            className: 'opacity',
            render() {
                let str = '';
                [20, 80, 100].forEach(n => {
                    str += `.${cssPrefix}opacity-${n}{}`
                })
                return str
            }
        },
        {
            // 绝对定位 方向 t-20vh top:20vh -m负数
            className: 'orientation',
            render() {
                let str = '';
                ['t', 'r', 'b', 'l', 'top', 'right', 'bottom', 'left'].forEach(trbl => {
                    ['m-', ''].forEach(m => {
                        NUM_WIDTH_UNIT.forEach(v => {
                            str += `.${cssPrefix}${trbl}-${m}${v}{}`
                        })
                    })
                })
                return str
            }
        },
        {
            // 鼠标样式方式枚举
            className: 'cursor',
            render() {
                let str = ''
                CURSOR_ENUM.forEach(v => {
                    str += `.${cssPrefix}cursor-${v}{}`
                })
                return str
            }
        },
        {
            // 文字折叠
            className: 'word-break',
            render() {
                let str = '';
                ['normal', 'break-all', 'keep-all', 'break-word', 'inherit', 'initial', 'unset'].forEach(v => {
                    str += `.${cssPrefix}word-break-${v}{}`
                })
                return str
            }
        },
        {
            // 字体粗细
            className: 'font-weight',
            render() {
                let str = '';
                ['font-weight', 'fw'].forEach(fw => {
                    [100, 200, 300, 400, 500, 600, 700, 800, 900, 'normal', 'bold', 'bolder', 'inherit', 'initial', 'lighter', 'normal', 'unset'].forEach(v => {
                        str += `.${cssPrefix}${fw}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            // 字体大小
            className: 'font-size',
            render() {
                let str = '';
                ['font-size', 'fs'].forEach(fs => {
                    NUM_ENUM.forEach(n => {
                        UNIT_ENUM.forEach(u => {
                            str += `.${cssPrefix}${fs}-${n}${u}{}`
                        })
                    })
                })
                return str
            }
        },
        // display
        {
            className: 'display',
            render() {
                let str = '';
                ['display', 'd'].forEach(d => {
                    DISPLAY_ENUM.forEach(v => {
                        str += `.${cssPrefix}${d}-${v}{}`
                    })
                })
                return str
            }
        },
        // overflow
        {
            className: 'overflow',
            render() {
                let str = '';
                ['x-', 'y-', ''].forEach(xy => {
                    ['hidden', 'auto', 'visible', 'scroll', 'inherit'].forEach(v => {
                        str += `.${cssPrefix}overflow-${xy}${v}{}`
                    })
                })
                return str
            }
        },
        {
            // letter-spacing
            className: 'letter-spacing',
            render() {
                let str = '';
                ['m-', ''].forEach(m => {
                    NUM_WIDTH_UNIT.forEach(v => {
                        str += `.${cssPrefix}letter-spacing-${m}${v}{}`
                    })
                })
                return str
            }
        },
        {
            // circle
            className: 'circle',
            render() {
                return '.circle'
            }
        },
        {
            // flexShrinkAndGrow
            className: 'flexShrinkAndGrow',
            render() {
                let str = '';
                ['shrink', 'grow'].forEach(sg => {
                    [...NUM_ENUM, 'initial', 'inherit'].forEach(v => {
                        str += `.${cssPrefix}flex-${sg}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            // flexBasis
            className: 'flex-basis',
            render() {
                let str = ''
                const list = [...NUM_WIDTH_UNIT, 'initial', 'inherit', 'auto']
                list.forEach(v => {
                    str += `.${cssPrefix}flex-basis-${v}{}`
                })
                return str
            }
        },
        {
            className: 'border',
            // 这个宽度没有百分比
            render() {
                let str = '';
                ['border', 'border-width', 'border-w'].forEach(bw => {
                    ['t-', 'r-', 'b-', 'l-', 'x-', 'y-', ''].forEach(trblxy => {
                        NUM_WIDTH_UNIT.forEach(v => {
                            str += `.${cssPrefix}${bw}-${trblxy}${v}{}`
                        })
                    })
                })
                return str
            }
        },
        {
            className: 'border-radius',
            render() {
                let str = '';
                ['border-radius', 'br'].forEach(br => {
                    NUM_WIDTH_UNIT.forEach(v => {
                        str += `.${cssPrefix}${br}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'border-style',
            render() {
                let str = '';
                ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset', 'inherit'].forEach(v => {
                    str += `.${cssPrefix}border-style-${v}{}`
                })
                return str
            }
        },
        {
            className: 'text-align-last',
            render() {
                let str = '';
                ['text-align-last', 'text-last'].forEach(tl => {
                    ['auto', 'left', 'right', 'center', 'justify', 'start', 'end', 'initial', 'inherit'].forEach(v => {
                        str += `.${cssPrefix}${tl}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'text-decoration',
            render() {
                let str = '';
                ['text-decoration', 'text'].forEach(text => {
                    ['none', 'underline', 'overline', 'line-through', 'blink', 'inherit'].forEach(v => {
                        str += `.${cssPrefix}${text}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'user-select',
            render() {
                let str = '';
                ['user-select', 'select'].forEach(s => {
                    ['none', 'auto', 'text', 'all', 'contain', 'element'].forEach(v => {
                        str += `.${cssPrefix}${s}-${v}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'vertical-align',
            render() {
                let str = '';
                [...VERTICAL_ALIGN_ENUM, ...NUM_WIDTH_UNIT].forEach(s => {
                    str += `.${cssPrefix}vertical-align-${s}{}`
                })
                return str
            }
        },
        {
            className: 'text-ellipsis-num',
            render() {
                let str = '';
                ['ellipsis', 'text', 'text-ellipsis'].forEach(t => {
                    ['', ...NUM_ENUM].forEach(n => {
                        str += `.${cssPrefix}${t}-${n}{}`
                    })
                })
                return str
            }
        },
        {
            // 所有有关颜色的
            className: 'color',
            render() {
                let str = '';
                ['color', 'c', 'text', 'bg', 'background', 'border-color', 'border-c'].forEach(t => {
                    COLORS_NAME_PRESET.forEach(c => {
                        ['', '-65', '-85'].forEach(o => {
                            str += `.${cssPrefix}${t}-${c}${o}{}`
                        })
                    })
                })
                return str
            }
        },
        {
            className: 'gap',
            render() {
                let str = '';
                [...GAP_ENUM, ...NUM_WIDTH_UNIT].forEach(s => {
                    str += `.${cssPrefix}gap-${s}{}`
                })
                return str
            }
        },
        {
            className: 'column-gap',
            render() {
                let str = '';
                ['c', 'column', 'r', 'row'].forEach(t => {
                    [...GAP_ENUM, ...NUM_WIDTH_UNIT].forEach(s => {
                        str += `.${cssPrefix}${t}-gap-${s}{}`
                    })
                })
                return str
            }
        },
        {
            className: 'visibility',
            render() {
                let str = '';
                ['visible', 'hidden', 'collapse', 'inherit', 'initial', 'revert', 'unset'].forEach(t => {
                    str += `.${cssPrefix}visibility-${t}{}`
                })
                return str
            }
        }
    ];
}

const fwFile = (str: any, flag: any) => {
    fs.writeFileSync(path.resolve(process.env.UNI_INPUT_DIR ?? process.cwd(), `./${SNIPPETS_FILE_NAME}`), str, {
        flag
    })
}

export const generator = (): void => {
    fwFile('', 'w');
    const snippetStr = getRegList().reduce((t, c) => `${t}${c.render()}`, '');
    fwFile(snippetStr, 'w');
    console.log(changeConsoleColor('autocss snippets created successfully by vite', 32));
}

if (process.env.COLOR) {
    fwFile('', 'w');
    const snippetStr = getRegList().reduce((t, c) => `${t}${c.render()}`, '');
    fwFile(snippetStr, 'w');
    console.log(changeConsoleColor('autocss snippets created successfully by bin'));
}
